package com.fuyin.controller.user;

import cn.hutool.system.SystemUtil;
import com.fuyin.commons.aop.OperationLogAnnotation;
import com.fuyin.commons.aop.RequestLogAnnotation;
import com.fuyin.commons.response.BaseResponse;
import com.fuyin.commons.response.ErrorCode;
import com.fuyin.commons.utils.MyUtils;
import com.fuyin.dao.GpDao;
import com.fuyin.dao.OperationLogDao;
import com.fuyin.dto.params.LoginParam;
import com.fuyin.dto.vo.GpDetails;
import com.fuyin.dto.vo.ModelReport;
import com.fuyin.dto.vo.RiskReport;
import com.fuyin.dto.vo.RzNeed;
import com.fuyin.entity.ReportInfo;
import com.fuyin.entity.User;
import com.fuyin.service.RedisService;
import com.fuyin.service.api.PythonApiService;
import com.fuyin.service.user.GpService;
import com.fuyin.service.user.UserService;
import io.swagger.annotations.*;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.ArrayList;

/**
 * @author yuanxilan (yuanxilan@keep.com)
 * @Description
 * @date 2021年10月23日 2:09 下午
 * @since
 */
@Api("用户接口")
@Controller
@RequestMapping(value = "/user")
@Slf4j
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private PythonApiService pythonApiService;

    @Autowired
    private GpService gpService;

    @Autowired
    private OperationLogDao operationLogDao;

    @Autowired
    private GpDao gpDao;

    @ApiOperation("用户登陆")
    @PostMapping(value = "/login")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "登陆成功"),
            @ApiResponse(code = 400, message = "参数不全"),
            @ApiResponse(code = 412, message = "账号不存在"),
            @ApiResponse(code = 413, message = "账号未启用"),
            @ApiResponse(code = 414, message = "账号密码错误"),
            @ApiResponse(code = 423, message = "验证码错误"),
            @ApiResponse(code = 424, message = "验证码超时")
    })
    @ResponseBody
    @RequestLogAnnotation
    @OperationLogAnnotation(operType = "登录日志", operDesc = "登录")
    public BaseResponse login(@RequestBody LoginParam loginParam, HttpServletRequest request) {
        MyUtils.checkParams("验证码和 key 不能为空", loginParam.getCode(), loginParam.getKey());
        if (!redisService.exists(loginParam.getKey())) {
            return BaseResponse.error(ErrorCode.VerificationCode_TIMEOUT, "验证码超时");
        }
        if (!redisService.get(loginParam.getKey()).equals(loginParam.getCode())) {
            return BaseResponse.error(ErrorCode.VerificationCode_ERROR, "验证码错误");
        }
        return userService.login(loginParam);
    }

    @GetMapping(value = "/test/{pageNum:[0-9]+}/{pageSize:[0-9]+}")
    @ResponseBody
    @OperationLogAnnotation(operType = "测试", operDesc = "测试")
    @RequestLogAnnotation
    public BaseResponse test(@RequestHeader("Authorization") String token, @PathVariable Integer pageNum, @PathVariable Integer pageSize) {
//        log.info("token: {}, name: {}", token, name);
//        log.info("token: {}", token);
//        log.info("获取空的 redis 值: {}", redisService.get("assert"));
//        Long startTime = System.currentTimeMillis();
//        pythonApiService.saveData("莎普爱思");
//        Long endTime = System.currentTimeMillis();
//        ExcelReader reader = ExcelUtil.getReader(FileUtil.file("/Users/yuanxilan/Desktop/工作簿1.xlsx"));
//        List<Map<String,Object>> readAll = reader.readAll();
//        for (Map<String,Object> a: readAll) {
//            log.info("b:{}", a);
//            log.info("c:{}", a.get("列1"));
//        }
//        reader.close();
//        List<String> agjcs = gpDao.getCompanyAgjcs();
//        for (String agjc : agjcs) {
//            try {
//                pythonApiService.saveData(agjc);
//                log.info("{} 已爬取完毕", agjc);
//            } catch (Exception e) {
//                XxlJobHelper.log(e);
//                log.warn("{} 爬取失败", agjc);
//            }
//        }
//        pythonApiService.saveData("莎普爱思");
        log.info("Java 运行时信息: {}", SystemUtil.getJavaRuntimeInfo());
        log.info("系统信息: {}", SystemUtil.getOsInfo());
        log.info("用户信息: {}", SystemUtil.getUserInfo());
        log.info("当前主机网络地址信息: {}", SystemUtil.getHostInfo());
        log.info("运行时信息，包括内存总大小、已用大小、可用大小等: {}", SystemUtil.getRuntimeInfo());
        return BaseResponse.error(1, "1");
    }

    @ApiOperation("用户注册")
    @PostMapping(value = "/register")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "注册成功"),
            @ApiResponse(code = 400, message = "参数不全"),
            @ApiResponse(code = 416, message = "重复注册"),
            @ApiResponse(code = 420, message = "邮箱已被注册"),
            @ApiResponse(code = 422, message = "密码不符合规范")
    })
    @ResponseBody
    @RequestLogAnnotation
    public BaseResponse register(@RequestBody LoginParam param, HttpServletRequest request) {
        return userService.register(param, request);
    }

//    @ApiOperation("内部接口，请勿访问")
//    @PostMapping(value = "/saveAccount")
//    @ResponseBody
//    public BaseResponse saveAccount(@RequestParam("token") String token1) {
//        return userService.saveAccount(token1);
//    }

    @ApiOperation("用户登出")
    @PostMapping(value = "/logout")
    @ResponseBody
    @RequestLogAnnotation
    @OperationLogAnnotation(operType = "登录日志", operDesc = "退出登录")
    public BaseResponse logout(@RequestHeader("Authorization") String token) {
        return userService.logout(token);
    }

    @ApiOperation("根据旧密码更新密码")
    @PostMapping(value = "/updatepasswordbyoldpassword")
    @ResponseBody
    @RequestLogAnnotation
    @ApiResponses(value = {
            @ApiResponse(code = 400, message = "参数不全"),
            @ApiResponse(code = 417, message = "新旧密码不能相同"),
            @ApiResponse(code = 412, message = "账号不存在"),
            @ApiResponse(code = 414, message = "账号密码错误"),
            @ApiResponse(code = 422, message = "新密码不符合规范")
    })
    @OperationLogAnnotation(operType = "操作日志", operDesc = "根据旧密码修改密码")
    public BaseResponse updatePasswordByOldPassword(@RequestBody ChangePasswordEntity entity) {
        return userService.updatePasswordByOldPassword(entity.getUserName(), entity.getOldPassword(), entity.getNewPassword());
    }

    @ApiOperation("根据爱好更新密码")
    @PostMapping(value = "/updatepasswordbyhobby")
    @ResponseBody
    @OperationLogAnnotation(operType = "操作日志", operDesc = "根据爱好修改密码")
    @Deprecated
    @RequestLogAnnotation
    public BaseResponse updatePasswordByHobby(@RequestBody LoginParam param) {
        return userService.updatePasswordByHobby(param.getUserName(), param.getPassword(), param.getHobby());
    }

    @ApiOperation("获取风险控制报告")
    @GetMapping(value = "/getriskreport")
    @ResponseBody
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "获取成功"),
            @ApiResponse(code = 400, message = "参数不全"),
            @ApiResponse(code = 418, message = "抓取不到股票信息"),
            @ApiResponse(code = 421, message = "暂时不支持该股票的爬取")
    })
    @RequestLogAnnotation
//    @OperationLogAnnotation(operType = "操作日志", operDesc = "获取风险控制报告")
    public BaseResponse<RiskReport> getRiskReport(@RequestHeader("Authorization") String token, @RequestParam @ApiParam("股票名") String gpName) {
        return gpService.getRiskReport(token, gpName);
    }

    @ApiOperation("获取个人信息")
    @ResponseBody
    @GetMapping("/getuserinfo")
    public BaseResponse<User> getUserInfo(@RequestHeader("Authorization") String token) {
        return userService.getUserInfo(token);
    }

    @ApiOperation("获取报告记录")
    @GetMapping(value = "/getreportinfo/{pageNum:[0-9]+}/{pageSize:[0-9]+}/{type:[0-1]+}")
    @ResponseBody
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "获取成功"),
            @ApiResponse(code = 400, message = "请求参数有误"),
            @ApiResponse(code = 401, message = "token 失效，请重新登录"),
            @ApiResponse(code = 412, message = "账号不存在")
    })
    @RequestLogAnnotation
    @OperationLogAnnotation(operType = "操作日志", operDesc = "获取报告记录")
    public BaseResponse<ArrayList<ReportInfo>> getReportInfo(@RequestHeader("Authorization") String token, @PathVariable Integer pageNum, @PathVariable Integer pageSize, @PathVariable Integer type) {
        return userService.getReportInfo(token, pageNum, pageSize, type);
    }

    @ApiOperation("获取融资方案分析报告")
    @PostMapping(value = "/getmodelreport")
    @ResponseBody
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "获取成功"),
            @ApiResponse(code = 400, message = "参数不全"),
            @ApiResponse(code = 418, message = "抓取不到股票信息"),
            @ApiResponse(code = 421, message = "暂时不支持该股票的爬取")
    })
    @RequestLogAnnotation
//    @OperationLogAnnotation(operType = "操作日志", operDesc = "获取融资方案分析报告")
    public BaseResponse<ModelReport> getModelReport(@RequestHeader("Authorization") String token, @RequestParam @ApiParam("股票名") String gpName, @RequestBody RzNeed rzNeed) {
        return gpService.getModelReport(token, rzNeed, gpName);
    }

    @ResponseBody
    @ApiOperation("获取能力分析")
    @PostMapping("/getanalysis")
    @RequestLogAnnotation
    public BaseResponse<ArrayList<RiskReport.Analysis>> getAnalysis(@RequestHeader("Authorization") String token, @RequestBody GpDetails gpDetails) {
        return gpService.getAnalysis(gpDetails);
    }

    @ResponseBody
    @ApiOperation("获取模型评估能力分析")
    @PostMapping("getmodelanalysis")
    @RequestLogAnnotation
    public BaseResponse<String> getModelAnalysis(@RequestHeader("Authorization") String token, @RequestBody GpDetails gpDetails) {
        return gpService.getModelAnalysis(gpDetails);
    }

    @OperationLogAnnotation(operType = "操作日志", operDesc = "导出报告")
    @ApiOperation("保存生成报告记录")
    @PostMapping("/saveriskreportinfo")
    @ResponseBody
    @RequestLogAnnotation
    public BaseResponse saveRiskReportInfo(@RequestHeader("Authorization") String token, @RequestBody RiskReport riskReport) {
        return gpService.saveRiskReportInfo(token, riskReport);
    }

    @OperationLogAnnotation(operType = "操作日志", operDesc = "导出报告")
    @ApiOperation("保存生成报告记录")
    @PostMapping("/savemodelreportinfo")
    @ResponseBody
    @RequestLogAnnotation
    public BaseResponse saveModelReportInfo(@RequestHeader("Authorization") String token, @RequestBody ModelReport modelReport) {
        return gpService.saveModelReportInfo(token, modelReport);
    }

    @Data
    public static class ChangePasswordEntity implements Serializable {

        private static final long serialVersionUID = 7436383832943378544L;

        @ApiModelProperty(value = "用户名", required = true)
        private String userName;

        @ApiModelProperty(value = "旧密码")
        private String oldPassword;

        @ApiModelProperty(value = "新密码", required = true)
        private String newPassword;

        @ApiModelProperty(value = "爱好")
        private String hobby;

    }
}
